from flask import Flask, render_template, request, send_file, jsonify
from flask_cors import CORS
import os
import json
import tempfile
import base64
import random
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 导入我们自己的模块
from beat_analyzer import analyze_audio_features, extract_features_for_chart_generation
from generate import generate_premium_chart, PremiumMaimaiChartGenerator
from chart_validator import ChartValidator

app = Flask(__name__)
CORS(app)  # 启用跨域支持
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024  # 100MB max file size

# 确保临时目录存在
os.makedirs('tmp', exist_ok=True)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/generate', methods=['POST'])
def generate_chart():
    try:
        # 获取JSON数据
        data = request.get_json()
        if not data:
            return jsonify({'error': '无效的请求数据'}), 400
        
        # 获取音频数据和参数
        audio_data = data.get('audio_data')
        level = data.get('level', '4')  # 更新默认等级为4
        difficulty = data.get('difficulty', '12')  # 更新默认难度为12
        
        if not audio_data:
            return jsonify({'success': False, 'error': '未提供音频数据'}), 400
        
        # 解码Base64音频数据
        try:
            # 移除数据URI前缀
            if audio_data.startswith('data:audio'):
                audio_data = audio_data.split(',')[1]
            elif audio_data.startswith('data:'):
                audio_data = audio_data.split(',')[1]
            
            audio_bytes = base64.b64decode(audio_data)
        except Exception as e:
            return jsonify({'success': False, 'error': f'音频数据解码失败: {str(e)}'}), 400
        
        # 创建临时文件保存音频
        with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as tmp_audio:
            tmp_audio.write(audio_bytes)
            audio_path = tmp_audio.name
        
        try:
            # 使用优化的音频特征分析函数
            features = extract_features_for_chart_generation(audio_path)
            
            if not features:
                return jsonify({
                    'success': False,
                    'error': '音频分析失败'
                }), 500
            
            # 解析难度数值，支持带"+"的格式如 "13+"
            try:
                difficulty_num = float(difficulty.replace("+", ".5")) if isinstance(difficulty, str) else float(difficulty)
            except ValueError:
                difficulty_num = 12.0
                
            # 所有难度都使用高质量生成器
            chart_content = generate_premium_chart(features, level, difficulty)
            
            # 无需再验证修复（由新函数保证质量）
            # 保存谱面文件
            chart_filename = f'chart_{random.randint(1000, 9999)}.txt'
            chart_filepath = os.path.join('tmp', chart_filename)
            with open(chart_filepath, 'w', encoding='utf-8') as f:
                f.write(chart_content)
            
            # 删除临时音频文件
            os.unlink(audio_path)
            
            return jsonify({
                'success': True,
                'message': '谱面生成成功！',
                'chart_file': chart_filename,
                'chart_content': chart_content
            })
            
        except Exception as e:
            # 清理临时文件
            if os.path.exists(audio_path):
                os.unlink(audio_path)
            raise e
                
    except Exception as e:
        return jsonify({'error': f'处理请求时出错: {str(e)}'}), 500

@app.route('/download/<filename>')
def download_chart(filename):
    """
    下载谱面文件
    """
    try:
        # 安全检查：防止路径遍历攻击
        if '..' in filename or '/' in filename or '\\' in filename:
            return jsonify({'success': False, 'error': '无效的文件名'}), 400
        
        file_path = os.path.join('tmp', filename)
        if not os.path.exists(file_path):
            return jsonify({'success': False, 'error': '文件不存在'}), 404
        
        return send_file(file_path, as_attachment=True, download_name='maidata.txt')
    except Exception as e:
        return jsonify({'success': False, 'error': f'下载文件时出错: {str(e)}'}), 500

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=32452)